home *** CD-ROM | disk | FTP | other *** search
- /*
- ** f u n c s . c
- **
- ** functions for UPS monitor daemon
- **
- ** Arthur W. Neilson III
- ** art@pilikia.pegasus.com
- ** Sat Mar 30 1991
- */
-
- #include <sys/ioctl.h>
- #include "common.h"
-
- /*
- ** g e t v a r s
- **
- ** retrieve environment variables
- */
- void
- getvars()
- {
- char *s, *getenv();
-
- if ((s = getenv(UPSPORT)) != NULL)
- ups_port = s;
- if ((s = getenv(UPSSHUT)) != NULL)
- ups_shut = s;
- if ((s = getenv(UPSLOG)) != NULL)
- ups_log = s;
- if ((s = getenv(UPSFAIL)) != NULL)
- ups_fail = s;
- if ((s = getenv(UPSREST)) != NULL)
- ups_rest = s;
- if ((s = getenv(UPSTIME)) != NULL)
- ups_time = atoi(s);
- }
-
- /*
- ** g e t o p t i o n s
- **
- ** retrieve and process command line options
- */
- void
- getoptions(ac, av)
- int ac;
- char *av[];
- {
- int c;
-
- void version();
- void usage();
-
- extern char *optarg;
- extern int optind, opterr;
-
- /* display program version */
- version(av[0]);
-
- /* parse the command line */
- while ((c = getopt(ac, av, "d:c:l:f:r:t:")) != EOF)
- switch (c) {
- case 'd': /* device option */
- ups_port = optarg;
- break;
- case 'c': /* command option */
- ups_shut = optarg;
- break;
- case 'l': /* logfile option */
- ups_log = optarg;
- break;
- case 'f': /* failure option */
- ups_fail = optarg;
- break;
- case 'r': /* restore option */
- ups_rest = optarg;
- break;
- case 't': /* time option */
- ups_time = atoi(optarg);
- break;
- case '\?': /* illegal option */
- usage(av[0]);
- exit(1);
- }
- }
-
- /*
- ** c h k o p t i o n s
- **
- ** check runtime options
- ** with various sanity tests
- */
- void
- chkoptions()
- {
- struct stat st;
- char *p, buf[64];
-
- /* UPS port must exist */
- if (stat(ups_port, &st) == ERR) {
- perror(ups_port);
- exit(1);
- }
- /* and must be character special */
- if ((st.st_mode & S_IFMT) != S_IFCHR) {
- fprintf(stderr, "%s not character special\n", ups_port);
- exit(1);
- }
- /* get command name out of shutdown command */
- strcpy(buf, ups_shut);
- if ((p = strtok(buf, " ")) == NULL)
- p = buf;
-
- /* shutdown command must exist */
- if (stat(p, &st) == ERR) {
- perror(ups_shut);
- exit(1);
- }
- /* and must be a regular file */
- if ((st.st_mode & S_IFMT) != S_IFREG) {
- fprintf(stderr, "%s not regular\n", ups_port);
- exit(1);
- }
- /* delay time must be > 0 and <= MAX_TIME */
- if (ups_time < 1 || ups_time > MAX_TIME) {
- fprintf(stderr, "time must be between 1 and %d\n", MAX_TIME);
- exit(1);
- }
- }
-
- /*
- ** m k d a e m o n
- **
- ** create daemon process
- */
- void
- mkdaemon()
- {
- char c;
- int stat;
- unsigned int modembits;
- unsigned int oldbits;
-
- void sigcatch();
- void writelog();
- void writeall();
- void shutdown();
-
- writelog(START_MSG);
-
-
-
- if (!fork()) {
-
- /* close standard files */
-
- close(0); /* stdin */
- close(1); /* stdout */
- close(2); /* stderr */
-
-
- setpgrp(); /* disassociate from terminal */
-
- /* ignore interrupts */
- signal(SIGHUP, SIG_IGN);
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
-
- /* catch termination signal */
- signal(SIGTERM, sigcatch);
-
- /* and shutdown on alarm */
- signal(SIGALRM, shutdown);
-
- /* open log file for append */
- if ((log_fd = open(ups_log, LOG_FLAGS, LOG_PERMS)) == ERR) {
- perror("could not open log file");
- exit(1);
- }
-
-
- /* and advisory lock it */
- /*
- if (lockf(log_fd, F_TLOCK, 0L) == ERR) {
- perror("could not open lock file");
- exit(1);
- }
- */
-
- writelog(START_MSG);
-
- ups_fd = open(ups_port,O_RDONLY,0);
- if (stat<0) {
- perror("cant open port");
- exit(1);
- }
- /* get old bits first time */
- stat = ioctl(ups_fd,TIOCMGET,&oldbits);
- while (1) {
-
- stat = ioctl(ups_fd,TIOCMGET,&modembits);
- if (modembits!=oldbits) {
-
- if (state==UPS_LINE) {
- state = UPS_BATTERY;
- } else {
- state = UPS_LINE;
- }
-
- switch(state) {
-
- case UPS_LINE :
- writelog(ONLINE_MSG);
- writeall(ups_rest);
- alarm(0);
-
- break;
-
- case UPS_BATTERY :
- writelog(BATTERY_MSG);
- writeall(ups_fail);
- alarm(ups_time * SECS_PER_MIN/4);
- break;
-
- }
- oldbits = modembits;
- }
-
- sleep(interval);
- }
-
-
-
- close(log_fd);
- close(ups_fd);
-
- } else {
-
- printf("process forked\n");
- }
- }
-
- /*
- ** s i g c a t c h
- **
- ** catch termination signal
- */
- void
- sigcatch()
- {
- writelog(TERM_MSG);
-
- close(log_fd);
- close(ups_fd);
-
-
- exit(1);
- }
-
- /*
- ** w r i t e l o g
- **
- ** write message to the UPS log file
- */
- void
- writelog(msg)
- char *msg;
- {
- time_t ticks;
- char *p, *ct;
- char msg_buf[80];
- char *strrchr();
-
- time(&ticks);
- ct = ctime(&ticks);
-
- /* find newline in buffer */
- if ((p = strrchr(ct, '\n')) != NULL)
- *p = NULL; /* and zap it */
-
- sprintf(msg_buf, "%s -- %s\n", ct, msg);
- write(log_fd, msg_buf, strlen(msg_buf));
- }
-
- /*
- ** w r i t e a l l
- **
- ** write to all users
- */
- void
- writeall(fn)
- char *fn;
- {
- struct stat st;
- void attach();
-
- /* message file must exist */
- if (stat(fn, &st) == ERR)
- return;
-
- /* and must be a regular file */
- if ((st.st_mode & S_IFMT) != S_IFREG)
- return;
-
- if (!fork()) {
-
- attach(CONSOLE);
-
- /* write message file to users */
- execlp(WALL, WALL, fn, NULL);
- }
- }
-
- /*
- ** s h u t d o w n
- **
- ** shutdown the system
- */
- void
- shutdown()
- {
- void attach();
-
- writelog(SHUTDOWN_MSG);
-
- close(ups_log);
- close(ups_port);
-
- if (!fork()) {
-
- attach(CONSOLE);
-
- chdir(ROOT);
-
- /* execute shutdown command */
- execlp(SH, SH, ups_shut, NULL);
- }
- }
-
- /*
- ** a t t a c h
- **
- ** attach standard i/o to a device
- */
- void
- attach(dev)
- char *dev;
- {
- int fd;
-
- /* close standard files */
- close(0); /* stdin */
- close(1); /* stdout */
- close(2); /* stderr */
-
- /* attach stdin to named device */
- if ((fd = open(dev, O_RDWR)) == ERR)
- exit(1);
- dup(fd); /* and stdout */
- dup(fd); /* and stderr */
- }
-
- /*
- ** b a s e n a m e
- **
- ** remove absolute path from filename
- **
- */
- char *
- basename(s)
- char *s;
- {
- register char *p;
-
- /* point to char after last '/' */
- if ((p = strrchr(s, '/')) != NULL)
- return (++p);
-
- return (s);
- }
-
- /*
- ** v e r s i o n
- **
- ** display program version
- */
- void
- version(s)
- char *s;
- {
- char *basename();
-
- /* display version in foreground */
- if (signal(SIGINT, SIG_IGN) != SIG_IGN)
- fprintf(stderr, "%s release %s version %d.%d patchlevel %d\n",
- basename(s), RELEASE_DATE, RELEASE, REVISION,
- PATCHLEVEL);
- }
-
- /*
- ** u s a g e
- **
- ** display program usage
- */
- void
- usage(s)
- char *s;
- {
- char *basename();
-
- fprintf(stderr, "usage: %s [-d tty][-c cmd][-l file][-f file][-r file][-t min]\n", basename(s));
- fprintf(stderr, "\t-d tty\t\tpathname of UPS device\n");
- fprintf(stderr, "\t-c cmd\t\tpathname of shutdown command\n");
- fprintf(stderr, "\t-l file\t\tpathname of UPS log file\n");
- fprintf(stderr, "\t-f file\t\tpathname of UPS fail message file\n");
- fprintf(stderr, "\t-r file\t\tpathname of UPS restore message file\n");
- fprintf(stderr, "\t-t min\t\tdelay time in minutes\n");
- }
-